package io.spring.start.site.gitlab;

import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.CommitAction;
import org.gitlab4j.api.models.CommitAction.Action;
import org.gitlab4j.api.models.CommitPayload;
import org.gitlab4j.api.models.Group;
import org.gitlab4j.api.models.GroupParams;
import org.gitlab4j.api.models.Project;
import org.gitlab4j.api.models.Visibility;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

import cn.hutool.core.io.IoUtil;
import io.spring.start.site.vo.GitlabVo;
import io.spring.start.site.vo.UploadFile;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class GitlabService {

	private GitLabApi gitLabApi;

	static String DOUBLE_SLASH = "\\";
	static String SINGLE_SLASH = "/";

	public GitlabService(GitLabApi gitLabApi) {
		this.gitLabApi = gitLabApi;
	}

	/**
	 * 判断是否存在项目
	 * @param groupIdOrPath
	 * @param projectIdOrPath
	 * @return
	 */
	public boolean existProject(String groupIdOrPath, String projectIdOrPath) {
		try {
			Optional<Project> optional = gitLabApi.getGroupApi()
				.getGroup(groupIdOrPath)
				.getProjects()
				.stream()
				.filter(p -> p.getName().equals(projectIdOrPath))
				.findFirst();
			if (optional.isPresent()) {
				return true;
			}
		}
		catch (GitLabApiException e) {
			log.error(e.getMessage(), e);
		}
		return false;
	}

	/**
	 * 根据项目名称和群组信息创建项目
	 * @param groupIdOrPath
	 * @param projectIdOrPath
	 * @return
	 */
	public Project createProject(GitlabVo gitlabVo, Group group) {
		Project project = new Project();
		try {
			project.setName(gitlabVo.getProjectName());
			project.setVisibility(Visibility.PRIVATE);
			project.setPath(gitlabVo.getProjectName());
			project.setDescription(gitlabVo.getProjectDescription());
			project = gitLabApi.getProjectApi().createProject(group.getId(), project);
		}
		catch (GitLabApiException e) {
			log.error(e.getMessage(), e);
		}
		return project;
	}

	/**
	 * 添加文件并上传至gitlab中
	 * @param project
	 * @param files
	 */
	public void addFile2Project(Project project, List<UploadFile> uploadFiles) {
		try {
			CommitPayload payload = new CommitPayload();
			payload.setAuthorEmail("liuwenlong62555@126.com");
			payload.setBranch("main");
			payload.setCommitMessage(project.getDescription());
			List<CommitAction> actions = Lists.newArrayList();

			for (UploadFile uploadFile : uploadFiles) {
				String rootDirectory = uploadFile.getRootDirectory().toString();
				Path path = uploadFile.getPath();
				if (!path.toFile().isDirectory()) {
					String filePath = StringUtils.substringAfter(path.toFile().toString(),
							rootDirectory + DOUBLE_SLASH);
					filePath = StringUtils.replaceChars(filePath, DOUBLE_SLASH, SINGLE_SLASH);
					CommitAction ca = new CommitAction();
					ca.setAction(Action.CREATE);
					ca.setContent(IoUtil.read(new FileInputStream(path.toFile()), StandardCharsets.UTF_8));
					ca.setFilePath(filePath);
					actions.add(ca);
					payload.setActions(actions);
				}
			}
			gitLabApi.getCommitsApi().createCommit(project.getId(), payload);
		}
		catch (Exception e) {
			log.error(e.getMessage(), e);
		}
	}

	/**
	 * 获取群组
	 * @param groupIdOrPath
	 * @return
	 */
	public Group getGroup(String groupIdOrPath) {
		Group group = null;
		try {
			group = gitLabApi.getGroupApi().getGroup(groupIdOrPath);
		}
		catch (GitLabApiException e) {
			log.error(e.getMessage(), e);
		}
		return group;
	}

	/**
	 * 创建群组
	 * @param groupIdOrPath
	 * @return
	 */
	public Group createGroup(String groupIdOrPath) {
		Group group = null;
		try {
			GroupParams params = new GroupParams();
			params.withName(groupIdOrPath).withPath(groupIdOrPath);
			group = gitLabApi.getGroupApi().createGroup(params);
		}
		catch (GitLabApiException e) {
			log.error(e.getMessage(), e);
		}
		return group;
	}

}
